package com.yssoft.datasource;

import com.yssoft.framework.redis.JedisBuilder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author 鲁菊平
 * @time 2025/11/05 下午 13:52
 * @ 监管企业管理 面向切面编程
 */
@Aspect
@Component
public class DataSourceAspect {
    private Logger logger = LoggerFactory.getLogger(DataSourceAspect.class);
    /**
     * 方法执行前：设置数据源
     *
     * @param point
     */
    @Before("execution(* com.yssoft.service..*.*(..))")
    public void before(JoinPoint point) {

        try {
            //TODO  第一步：直接获取目标类的方法
            Object target = point.getTarget();
            MethodSignature signature = (MethodSignature) point.getSignature();
            //从目标类中获取执行方法
            Method method = target.getClass().getMethod(
                    signature.getMethod().getName(),
                    signature.getMethod().getParameterTypes()
            );
            //TODO 第二步：使用多种方式查找注解，并向线程池中设置数据源
            DataSource methodDataSource = findDataSourceAnnotation(method, target.getClass());
            if (methodDataSource != null) {
                // 找到注解，设置数据源
                String dataSourceValue = methodDataSource.value();
                DataSourceContextHolder.setDataSource(dataSourceValue);
                return;
            } else {
                // 打印所有注解信息
                Annotation[] annotations = method.getAnnotations();
              logger.info("方法上的所有注解: " + Arrays.toString(annotations));
            }
            //如果未找到注解，设置默认数据源
            DataSourceContextHolder.setDataSource(DataSourceContextHolder.MYSQL);
        } catch (Exception e) {
            logger.error("数据源定义失败" +e.getMessage());
            DataSourceContextHolder.setDataSource(DataSourceContextHolder.MYSQL);
        }
    }

    /**
     * 查找注解
     */
    private DataSource findDataSourceAnnotation(Method method, Class<?> targetClass) {
        // 1：直接从方法获取注解
        DataSource annotation = method.getAnnotation(DataSource.class);
        if (annotation != null) {
            return annotation;
        }
        // 2：使用 AnnotationUtils类中获取注解
        annotation = AnnotationUtils.findAnnotation(method, DataSource.class);
        if (annotation != null) {
            return annotation;
        }

        //3：从类上获取注解
        annotation = targetClass.getAnnotation(DataSource.class);
        if (annotation != null) {
            return annotation;
        }

        // 4：使用 AnnotationUtils 从类上获取注解
        annotation = AnnotationUtils.findAnnotation(targetClass, DataSource.class);
        if (annotation != null) {
            return annotation;
        }

        return null;
    }

    /**
     * 方法执行后：清理线程锁
     * @param point
     */
    @After("execution(* com.yssoft.service..*.*(..))")
    public void after(JoinPoint point) {
        DataSourceContextHolder.clearDataSource();
    }

}